from .models import Order, OrderDetail, GoodsShelf
from rest_framework import serializers
from rest_framework.exceptions import APIException
from django.conf import settings
from car.models import ShopCar


class OrderDetailSerializer(serializers.ModelSerializer):
    class Meta:
        model = OrderDetail
        fields = '__all__'


class OrderSerializer(serializers.ModelSerializer):
    addr_info = serializers.DictField()
    order_goods = OrderDetailSerializer(many=True)

    class Meta:
        model = Order
        fields = [
            'id',
            'user_name',
            'subject',
            'order_form',
            'order_status',
            'order_status_name',
            'trade_no',
            'order_total_amount',
            'user',
            'buy_num',
            'pay_status_name',
            'pay_type_name',
            'pay_time',
            'created_time',
            'commodity_list',
            'addr_info',
            'order_goods',
            'url'
        ]


class PaySuccessSerializer(serializers.ModelSerializer):
    # goods = serializers.PrimaryKeyRelatedField(queryset=GoodsShelf.objects.all(), write_only=True, many=True)
    class Meta:
        model = Order
        fields = [
            'user_name',
            'subject',
            'order_total_amount',
            'user',
            'buy_num',
            'pay_type',
            'commodity_list',
            'addr_info',
            'addr_id',
        ]

    commodity_list = serializers.ListField(write_only=True)
    addr_info = serializers.DictField(write_only=True)
    order_total_amount = serializers.IntegerField(write_only=True)
    addr_id = serializers.IntegerField(write_only=True)

    def _check_price(self, attrs):
        goods_info = attrs.get('commodity_list')[0]
        real_total = 0
        if goods_info.get('user_id'):
            real_total = 0
            for car in attrs.get('commodity_list'):
                car_id = car.get('id')
                item = ShopCar.objects.filter(id=car_id).values()[0]
                buy_num = item.get('buy_num')
                price = GoodsShelf.objects.filter(id=item.get('goods_id')).values()[0].get('selling_price')
                real_total += buy_num * price
                continue
            total_amount = attrs.get('order_total_amount')
            if total_amount != real_total:
                raise APIException('价格不一致')
            else:
                return real_total
        else:
            goods_id = goods_info.get('goods_info').get('id')
            buy_num = goods_info.get('buy_num')
            price = GoodsShelf.objects.filter(id=goods_id).values()[0].get('selling_price')
            real_total += buy_num * price
            total_amount = attrs.get('order_total_amount')
            if total_amount != real_total:
                raise APIException('价格不一致')
            else:
                return real_total

    def _get_trade_no(self):
        import uuid
        return str(uuid.uuid4())

    def _get_user(self):
        request = self.context.get('request')
        return request.user

    def _get_pay_url(self, total_amount, subject, trade_no):
        from libs.alipay_common import GATEWAY, alipay
        pay_str = alipay.api_alipay_trade_page_pay(
            out_trade_no=trade_no,
            total_amount=float(total_amount),
            subject=subject,
            return_url=settings.RETURN_URL,
            notify_url=settings.NOTIFY_URL,
        )
        return GATEWAY + pay_str

    def _before_create(self, pay_url, attrs, user, trade_no):
        self.context['pay_url'] = pay_url
        attrs['user'] = user
        attrs['order_form'] = trade_no
        attrs['url'] = pay_url

    def validate(self, attrs):
        total_amount = self._check_price(attrs)
        trade_no = self._get_trade_no()
        user = self._get_user()
        pay_url = self._get_pay_url(total_amount, attrs.get('subject'), trade_no)
        self._before_create(pay_url, attrs, user, trade_no)
        return attrs

    def create(self, validated_data):
        orders = validated_data.pop('commodity_list')
        addr = validated_data.pop('addr_info')
        order = Order.objects.create(**validated_data)
        for goods in orders:
            OrderDetail.objects.create(order=order, addr_id=addr.get('address_id'),
                                       goods_id=goods.get('goods_info').get('id'),
                                       price=goods.get('goods_info').get('price'),
                                       real_price=goods.get('goods_info').get('original_price'),
                                       buy_num=goods.get('buy_num')
                                       )
        return order
